home *** CD-ROM | disk | FTP | other *** search
/ Developer CD Series 1996 February: Tool Chest / Apple Developer CD Series Tool Chest February 1996 (Apple Computer)(1996).iso / Sample Code / AOCE Sample Code / PowerTalk Access Modules / Sample SMSAM / SampleSMSAM Source / 2020HalfGateway / 2020Recipient.cp < prev    next >
Encoding:
Text File  |  1995-07-28  |  20.6 KB  |  740 lines  |  [TEXT/MPS ]

  1. /*
  2.     File:        2020Recipient.cp
  3.  
  4.     Copyright:    © 1991-1994 by Apple Computer, Inc.
  5.                 All rights reserved.
  6.  
  7.     Part of the AOCE Sample SMSAM Package.  Consult the license
  8.     which came with this software for your specific legal rights.
  9.  
  10. */
  11.  
  12.  
  13.  
  14. #ifndef __BLJSTANDARDINCLUDES__
  15. #include "BLJStandardIncludes.h"
  16. #endif
  17.  
  18. #ifndef __AYSTHREADGLUE__
  19. #include "AYSThreadGlue.h"
  20. #endif
  21.  
  22. #ifndef __2020RECIPIENT__
  23. #include "2020Recipient.h"
  24. #endif
  25.  
  26. #ifndef __2020HALFGATEWAY__
  27. #include "2020HalfGateway.h"
  28. #endif
  29.  
  30. #ifndef __BLJOCEUTILITIES__
  31. #include "BLJOCEUtilities.h"
  32. #endif
  33.  
  34. #ifndef __OCEERRORS__
  35. #include <OCEErrors.h>
  36. #endif
  37.  
  38. #ifndef __UTILITIES__
  39. #include "Utilities.h"
  40. #endif
  41.  
  42. #ifndef __DEBUGGINGGEAR__
  43. #include "DebuggingGear.h"
  44. #endif
  45.  
  46. #ifndef    __DEBUGASSERT__
  47. #include "DebugAssert.h"
  48. #endif
  49.  
  50. #ifndef __2020LETTER__
  51. #include "2020Letter.h"
  52. #endif
  53.  
  54. #pragma segment T2020Recipient
  55.  
  56. /***********************************|****************************************/
  57.  
  58. #if 0
  59. Boolean ConvertDNodeToPackedPathName ( const RLI* aRLI, PackedPathName* packedPathPtr, unsigned short packedPathPtrSize, AuthIdentity identity )
  60. {
  61.     if ( aRLI && ( aRLI->dNodeNumber != kNULLDNodeNumber ) )
  62.     {
  63.         DirMapDNodeNumberToPathNamePB pb;
  64.  
  65.         memset (&pb, 0, sizeof(pb));
  66.  
  67.         pb.identity = identity;
  68.         pb.directoryName = aRLI->directoryName;
  69.         pb.discriminator = aRLI->discriminator;
  70.         pb.dNodeNumber = aRLI->dNodeNumber;
  71.         pb.path = packedPathPtr;
  72.         pb.lengthOfPathName = (unsigned short) packedPathPtrSize;
  73.  
  74.         OSErr err = DirMapDNodeNumberToPathName((DirParamBlockPtr) &pb, false);
  75.  
  76.         const char * GetErrorText ( OSErr err );
  77.         if ( err != noErr )
  78.             keith << "T2020Recipient, ConvertDNodeToPackedPathName, err=" << err << " " << GetErrorName ( err ) << endl << flush;
  79.  
  80.         return err == noErr;
  81.     }
  82.  
  83.     return false;
  84. }
  85. #endif
  86.  
  87. /***********************************|****************************************/
  88.  
  89. T2020Recipient::T2020Recipient(T2020Letter* owningLetter, const OCEPackedRecipient *recipient, unsigned short originalRecipientIndex, Boolean responsible, Boolean marked) :
  90.     fOwningLetter(owningLetter),
  91.     fRecipient ( (PackedDSSpec*) recipient ),
  92.     fResponsible ( responsible ),
  93.     fOriginalRecipientIndex ( originalRecipientIndex ),
  94.     fResolvedRecipientIndex ( 0 ),
  95.     fStatus ( cUnknown ),
  96.     fCheckedWhetherPathInformationIsOptional ( false ),
  97.     fIsPathInfoOptional ( false ),
  98.     fCheckedWhetherRecipientNameIsUnique ( false ),
  99.     fRecipientNameIsUnique ( false )
  100. {
  101. #if false
  102.     keith << "OCEPackedRecipient structure is " << endl;
  103.     DumpHex (keith, (char *) recipient, recipient->dataLength + sizeof(OCEPackedRecipient)); keith << endl;
  104. #endif
  105.  
  106.     ASSERT_RETURN ( recipient != nil );
  107.  
  108.  
  109.  
  110.     #if 0
  111.  
  112.     const unsigned long recipientPhysicalLength = recipient->dataLength + sizeof ( ProtoOCEPackedRecipient );
  113.     ASSERT_RETURN ( recipientPhysicalLength <= kOCEPackedRecipientMaxBytes );
  114.     fOCEPackedRecipient = (OCEPackedRecipient*) FAILNewPtr ( recipientPhysicalLength );
  115.     BlockMove ( recipient, fOCEPackedRecipient, recipientPhysicalLength );
  116.  
  117.     fRecordID = (RecordIDPtr) FAILNewPtr(sizeof(*fRecordID));
  118.     fOCERecipient.entitySpecifier = fRecordID;
  119.     OCEUnpackRecipient (fOCEPackedRecipient, &fOCERecipient, fOCERecipient.entitySpecifier);
  120.  
  121. #if debug
  122.     if (OCEValidPackedRLI(fRecordID->rli) == false) {
  123.         keith << "*** T2020Recipient:T2020Recipient, ValidPackedRLI(rli) FAILED, continuing." << endl << flush;
  124.     }
  125. #endif
  126.  
  127.     fRLI = (RLI*) FAILNewPtr ( fRecordID->rli->dataLength + sizeof ( ProtoPackedRLI ) );
  128.     OCEUnpackRLI ( fRecordID->rli, fRLI );
  129.  
  130.     //    OK.  Now, we either have a dNodeNumber in this address (in which case we need to
  131.     //    generate the packed path to accompany it), or we've got the packed path (in
  132.     //    which case we need to figure out it's dNodeNumber.)  We postpone getting the dNodeNumber
  133.     //    from the packed path until it's actually asked for (because it won't be used most of the
  134.     //    time).
  135.  
  136.     if (fRLI->dNodeNumber != kNULLDNodeNumber)
  137.     {
  138.         #if 1
  139.         TPathName pathName;
  140.         fOwningLetter-> GetHalfGateway()->FindPathNameForDNode ( fRLI->dNodeNumber,
  141.                                                                     TDirectory ( fRLI->directoryName, fRLI-> discriminator ),
  142.                                                                     pathName );
  143.         fPackedPathNamePtr = (PackedPathNamePtr) FAILNewPtr ( (( const PackedPathName*) pathName)->dataLength + sizeof(ProtoPackedPathName) );
  144.         FAILOSErr ( OCECopyPackedPathName ( (const PackedPathName*) pathName, fPackedPathNamePtr, GetPtrSize ( (Ptr) fPackedPathNamePtr) ) );
  145.  
  146.         #else
  147.  
  148.         PackedPathName tempPathName;
  149.  
  150.         if ( ConvertDNodeToPackedPathName ( fRLI, &tempPathName, sizeof ( tempPathName ), fOwningLetter->GetHalfGateway()->GetForwarderIdentity() ) )
  151.         {
  152.             const unsigned long pathNameSize = tempPathName.dataLength + sizeof ( ProtoPackedPathName );
  153.             fPackedPathNamePtr = (PackedPathName*) FAILNewPtr ( pathNameSize );
  154.             BlockMove ( &tempPathName, fPackedPathNamePtr, pathNameSize );
  155.         }
  156.         else
  157.             fPackedPathNamePtr = nil;
  158.  
  159.         fRLI->path = fPackedPathNamePtr;
  160.         fPathNameItems = nil;
  161.         #endif
  162.     }
  163.  
  164.     TRY
  165.         if (fRLI->path)
  166.         {    if (OCEValidPackedPathName(fRLI->path))
  167.             {
  168.                 fPathNameItemsCount = OCEDNodeNameCount(fRLI->path);
  169.                 fPathNameItems = (RStringPtr*) FAILNewPtr(sizeof(fPathNameItems[0]) * fPathNameItemsCount);
  170.                 if (fPathNameItems)
  171.                     OCEUnpackPathName (fRLI->path, fPathNameItems, fPathNameItemsCount);
  172.             }
  173.             else
  174.             {
  175.                 keith << "[invalid path] " << flush;
  176.             }
  177.         }
  178.  
  179.     EXCEPTION
  180.         PASSEXCEPTION();
  181.  
  182.     ENDEXCEPTION;
  183.  
  184.     #endif
  185.  
  186. }
  187.  
  188. /***********************************|****************************************/
  189.  
  190. T2020Recipient::~T2020Recipient()
  191. {
  192.     keithF ( 1, "T2020Recipient::~T2020Recipient, " << fRecipient );
  193.  
  194.     #if 0
  195.     DisposeIfPtr ((Ptr) fPackedPathNamePtr);
  196.     DisposeIfPtr ((Ptr) fPathNameItems);
  197.     DisposeIfPtr ((Ptr) fRecordID);
  198.     DisposeIfPtr ((Ptr) fRLI);
  199.     DisposeIfPtr ((Ptr) fOCEPackedRecipient);
  200.     #endif
  201. }
  202.  
  203. /***********************************|****************************************/
  204.  
  205. #if 0
  206.  
  207. /***********************************|****************************************/
  208.  
  209. Boolean IsRecordIsUserAliasRecord ( const TRecord& record )
  210. {
  211.     return false;
  212. }
  213.  
  214. /***********************************|****************************************/
  215.  
  216. PackedDSSpecHandle FAILNewDSSpecHandle ( const DSSpec* originalH )
  217. {
  218.     PackedDSSpecHandle result = FAILNewHandle ( (**originalH).dataLength + sizeof ( ProtoPackedDSSpec ) );
  219.     if ( result )
  220.     {
  221.         FAILOSErr ( OCECopyPackedDSSpec ( *originalH, *resultH, (**originalH).dataLength );
  222.     }
  223.     
  224.     return result;
  225. }
  226.  
  227. /***********************************|****************************************/
  228.  
  229. Boolean T2020Recipient::Initialize ( )
  230. {
  231.     //    If the record is an alias, then we need to resolve the alias and
  232.     //    use the real record.    
  233.  
  234.     if ( IsRecordIsUserAliasRecord ( fRecipient ) )
  235.     {
  236.         PackedDSSpecHandle dsSpecH = nil;
  237.         
  238.         TRY
  239.             dsSpecH = FAILNewDSSpecHandle ( (const DSSpec*) fRecipient );
  240.         
  241.             if ( SDPResolveAliasFile( dsSpecH, GetOwningGateway()->GetForwarderIdentity(), false ) == noErr )
  242.             {
  243.                 //    Replace the recipient ( which is an alias ) with the original
  244.                 //    record. 
  245.                 HLock ( (Handle) dsSpecH );
  246.                 fRecipient = TDSSpec ( *dsSpecH );
  247.             }
  248.         
  249.         EXCEPTION
  250.         
  251.         ENDEXCEPTION
  252.         
  253.         DisposeIfHandle ( (Handle) dsSpecH );
  254.     }
  255.     
  256.     fInitialized = true;
  257. }
  258.  
  259. #endif
  260.  
  261. /***********************************|****************************************/
  262.  
  263. #if 0
  264. Boolean ConvertPackedPathnameToDNode (RLI* aRLI, AuthIdentity identity) {
  265.  
  266.     if (aRLI && aRLI->path && (OCEIsNullPackedPathName(aRLI->path) == false)) {
  267.         DirMapPathNameToDNodeNumberPB    pb;
  268.  
  269.         memset (&pb, 0, sizeof(pb));
  270.         pb.directoryName = aRLI->directoryName;
  271.         pb.discriminator = aRLI->discriminator;
  272.         pb.path = aRLI->path;
  273.  
  274.         OSErr err = DirMapPathNameToDNodeNumberSleep( (DirParamBlockPtr) &pb );
  275.         if ( err == kOCEStreamCreationErr )
  276.             err = DirMapPathNameToDNodeNumberSleep( (DirParamBlockPtr) &pb );
  277.  
  278.         #if debug
  279.         if ( err )
  280.             keithF ( 1, "ConvertPackedPathNameToDNode, err=" << err );
  281.         #endif
  282.  
  283.         if (err == noErr) {
  284.             aRLI->dNodeNumber = pb.dNodeNumber;
  285.         }
  286.         return (err == noErr);
  287.     }
  288.     return false;
  289. }
  290. #endif
  291.  
  292. /***********************************|****************************************/
  293.  
  294. Boolean T2020Recipient::GetResponsible () const
  295. {
  296.     keithF ( 15, "T2020Recipient::Responsible(), " << fRecipient << ", result = " << (short) fResponsible );
  297.  
  298.     return fResponsible;
  299. }
  300.  
  301. /***********************************|****************************************/
  302.  
  303. Boolean T2020Recipient::GetRecipientName (TRString& name) const
  304. {    Boolean result = false;
  305.  
  306.     #if old
  307.     OCECopyRString (fOCERecipient.entitySpecifier->local.recordName, &name, kRStringMaxBytes);
  308.     #else
  309.     fRecipient.GetRecordName ( name );
  310.     #endif
  311.  
  312.     keithF ( 15, "T2020Recipient::GetRecipientName() name=" << name );
  313.  
  314.     return ( name.GetLength() > 0 );
  315. }
  316.  
  317.  
  318. /***********************************|****************************************/
  319.  
  320. Boolean T2020Recipient::GetRecipientType (TRString& type) const
  321. {
  322.     #if 0
  323.     OCECopyRString (fOCERecipient.entitySpecifier->local.recordType, &type, kRStringMaxBytes);
  324.     #else
  325.     fRecipient.GetRecordType ( type );
  326.     #endif
  327.  
  328.     keithF ( 15, "T2020Recipient::GetRecipientType(), " << fRecipient << ", type=" << type );
  329.  
  330.     return ( type.GetLength() > 0 );
  331. }
  332.  
  333. /***********************************|****************************************/
  334.  
  335. Boolean T2020Recipient::GetDirectoryName (DirectoryName& directoryName) const {
  336.  
  337.     TDirectory directory;
  338.     fRecipient.GetDirectory ( directory );
  339.     OCECopyRString ( directory.GetName(), (RStringPtr) &directoryName, kDirectoryNameMaxBytes );
  340.  
  341.     keithF ( 15, "T2020Recipient::GetDirectoryName(), " << fRecipient << ", dirName=" << directoryName );
  342.  
  343.     return ( directoryName.dataLength > 0 );
  344. }
  345.  
  346. /***********************************|****************************************/
  347.  
  348. Boolean T2020Recipient::GetPathDNode (unsigned long& dNode) const
  349. {
  350.     dNode = fRecipient.GetNode();
  351.  
  352.     return true;
  353. }
  354.  
  355. /***********************************|****************************************/
  356.  
  357. unsigned short T2020Recipient::GetPathNameCount () const
  358. {
  359.     TPathName path;
  360.     if ( fRecipient.GetPathName( path ) == false )
  361.     {
  362.         //    The recipient doesn't 'have' a path name, so look up the path name
  363.         //    from the dNode and then stuff that path name into the recipient.
  364.  
  365.         TDirectory directory;
  366.         if ( fRecipient.GetDirectory( directory ) &&
  367.                 fOwningLetter->GetHalfGateway()->FindPathNameForDNode ( fRecipient.GetNode(), directory, path ) )
  368.         {
  369.             ((T2020Recipient*) this)->fRecipient.SetPathName ( path );
  370.         }
  371.     }
  372.  
  373.     return path.GetNodeCount();
  374. }
  375.  
  376. /***********************************|****************************************/
  377.  
  378. void T2020Recipient::GetPathNameItem (unsigned short item, TRString& nodeName) const
  379. {
  380.     if ( ( item > 0 ) && ( item <= GetPathNameCount () ) )
  381.     {
  382.         TPathName path;
  383.         if ( fRecipient.GetPathName ( path ) )
  384.         {
  385.             path.GetNode ( item, nodeName );
  386.             return;
  387.         }
  388.     }
  389.  
  390.     nodeName.SetLength( 0 ) ;
  391.     nodeName.SetScript ( smRoman );
  392. }
  393.  
  394. /***********************************|****************************************/
  395.  
  396. Boolean T2020Recipient::GetCID (CreationID& cid)  const
  397. {    TCreationID id;
  398.  
  399.     fRecipient.GetCreationID ( id );
  400.     OCECopyCreationID ( id, & cid );
  401.  
  402.     return ((cid.source != 0) || (cid.seq != 0));
  403. }
  404.  
  405. /***********************************|****************************************/
  406.  
  407. OSType T2020Recipient::GetAddressType () const
  408. {
  409.     if ( IsAddressTypePresent () )
  410.         return fRecipient.GetExtensionType() ;
  411.     else
  412.         return kOCEInvalidDSSpec;
  413. }
  414.  
  415. /***********************************|****************************************/
  416.  
  417. typedef struct AOCEALANExtensionDataStruct {
  418.     Str32                nbpName;
  419.     Str32                nbpType;
  420.     Str32                nbpZone;
  421.     Str32                messageQueue;
  422. } AOCEALANExtensionDataStruct;
  423.  
  424. /***********************************|****************************************/
  425.  
  426. const StringPtr UnpackItem ( const void * & p )
  427. {
  428.     const StringPtr result = (const StringPtr) p;
  429.  
  430.     p = ( const void*) ( ((char*) p ) + 1 + * ( unsigned char *) p );
  431.  
  432.     return result;
  433. }
  434.  
  435. /***********************************|****************************************/
  436.  
  437. inline void StringCopy ( StringPtr dest, StringPtr source, unsigned long maxLength )
  438. {
  439.     if ( source[0] <= maxLength )
  440.         BlockMove ( source, dest, 1 + source[0] );
  441.     else
  442.         dest[0] = 0;
  443. }
  444.  
  445. /***********************************|****************************************/
  446.  
  447. inline void StringCopyExclude ( StringPtr dest, StringPtr source, unsigned long maxLength, const StringPtr dontCopyIfSourceIsThisString )
  448. {
  449.     dest[0] = 0;
  450.     if ( source[0] <= maxLength )
  451.         if ( ! EqualString ( source, dontCopyIfSourceIsThisString, false, false ) )
  452.             BlockMove ( source, dest, 1 + source[0] );
  453. }
  454.  
  455. /***********************************|****************************************/
  456.  
  457. static void UnpackAOCEALANAddress ( const void * packedALANData, AOCEALANExtensionDataStruct& values )
  458. {
  459.     StringCopy ( (StringPtr) & values.nbpName, UnpackItem ( packedALANData ), 31 );
  460.     StringCopyExclude ( (StringPtr) & values.nbpType, UnpackItem ( packedALANData ), 31, "\pMsgReceiver" );
  461.     StringCopy ( (StringPtr) & values.nbpZone, UnpackItem ( packedALANData ), 31 );
  462.     StringCopyExclude ( (StringPtr) & values.messageQueue, UnpackItem ( packedALANData ), 31, "\pInMail_Queue" );
  463. }
  464.  
  465. /***********************************|****************************************/
  466.  
  467. unsigned long T2020Recipient::GetExtensionDataSize () const
  468. {
  469.     switch ( GetAddressType() )
  470.     {
  471.         case 'alan':
  472.             return sizeof ( AOCEALANExtensionDataStruct );
  473.  
  474.         case 'entn':
  475.             return 0;
  476.  
  477.         default:
  478.             return fRecipient.GetExtensionSize() - sizeof(ProtoRString);
  479.     }
  480. }
  481.  
  482. /***********************************|****************************************
  483.  *
  484.  *    T2020Recipient::GetExtensionData()
  485.  *
  486.  *    Return the extension data for this address.  AOCE 'entn' addresses don't
  487.  *    have extension data.  For most addresses, just return the extension data
  488.  *    ( minus the RString header part ).  But, some addresses are going to
  489.  *    have to be special cased.  Right now, the 'alan' address type will be
  490.  *    treated differently and will return a 'struct' of data which is a
  491.  *    packed NBP address followed by a pascal-style string.
  492.  *
  493.  ***********************************|****************************************/
  494.  
  495. void T2020Recipient::GetExtensionData (unsigned long offset, void *buffer, unsigned long bufferSize)  const
  496. {
  497.     long dataSize = GetExtensionDataSize();
  498.  
  499.     if ((buffer) && (offset < dataSize))
  500.     {
  501.         switch ( GetAddressType() )
  502.         {
  503.             default:
  504.                 BlockMove (    (Ptr) ((char *) fRecipient.GetExtensionValue() + sizeof(ProtoRString) + offset),
  505.                             (Ptr) buffer, longmin( bufferSize, dataSize-offset ) );
  506.                 break;
  507.  
  508.             case 'entn':
  509.                 break;
  510.  
  511.             case 'alan':    //    Unpack the data into a AOCEALANExtensionDataStruct, then return it.
  512.             {    AOCEALANExtensionDataStruct    extensionValue;
  513.  
  514.                 UnpackAOCEALANAddress ( fRecipient.GetExtensionValue(), extensionValue );
  515.  
  516.  
  517.                 BlockMove (    (Ptr) ((char *) &extensionValue + offset),
  518.                             (Ptr) buffer, longmin( bufferSize, dataSize-offset ) );
  519.                 break;
  520.             }
  521.         }
  522.     }
  523. }
  524.  
  525. /***********************************|****************************************/
  526.  
  527. ostream& T2020Recipient::DescribeSubclass(ostream& s) const
  528. {
  529.     return s << "T2020Recipient: fOrigIndex=" << fOriginalRecipientIndex << " fRslvdIndex=" << fResolvedRecipientIndex << flush;
  530. }
  531.  
  532. /***********************************|****************************************/
  533.  
  534. ostream& T2020Recipient::operator >> ( ostream& s ) const
  535. {
  536.     s << "T2020Recipient: ";
  537.     if (this == nil)
  538.     {
  539.         s << "nil?" << flush;
  540.         return s;
  541.     }
  542.  
  543.     TRString name;
  544.     if (GetRecipientName(name))
  545.         s << name << " ";
  546.     else
  547.     {    CreationID    id;
  548.  
  549.         if (GetCID(id))
  550.             s << id << " ";
  551.         else
  552.         {
  553.             char extensionData[24];
  554.             GetExtensionData(0, extensionData, sizeof(extensionData));
  555.             s << "[" << extensionData << " " << OutputOSType(s, GetAddressType()) << "] ";
  556.         }
  557.     }
  558.  
  559.     s << " status=" << (short) GetStatus() << " ";
  560.  
  561.     s << "OrigIndex=" << (short) fOriginalRecipientIndex << " ";
  562.     s << "RslvdIndex=" << (short) fResolvedRecipientIndex << " " << flush;
  563.  
  564.     return s;
  565. }
  566.  
  567. /***********************************|****************************************/
  568.  
  569. unsigned short T2020Recipient::GetOriginalRecipientIndex ()  const
  570. {
  571.     return fOriginalRecipientIndex;
  572. }
  573.  
  574. /***********************************|****************************************/
  575.  
  576. void T2020Recipient::SetOriginalRecipientIndex (unsigned short index)
  577. {
  578.     fOriginalRecipientIndex = index;
  579. }
  580.  
  581. /***********************************|****************************************/
  582.  
  583. unsigned short T2020Recipient::GetResolvedRecipientIndex ()  const
  584. {
  585.     return fResolvedRecipientIndex;
  586. }
  587.  
  588. /***********************************|****************************************/
  589.  
  590. void T2020Recipient::SetResolvedRecipientIndex (unsigned short index)
  591. {
  592.     fResolvedRecipientIndex = index;
  593. }
  594.  
  595. /***********************************|****************************************/
  596.  
  597. void T2020Recipient::SetResponsible (Boolean responsible)
  598. {
  599.     fResponsible = responsible;
  600. }
  601.  
  602. /***********************************|****************************************/
  603.  
  604. Boolean T2020Recipient::GetHidden () const
  605. {
  606.     return fHidden;
  607. }
  608.  
  609. /***********************************|****************************************/
  610.  
  611. void T2020Recipient::SetHidden (Boolean hidden)
  612. {
  613.     fHidden = hidden;
  614. }
  615.  
  616. /***********************************|****************************************/
  617.  
  618. Boolean T2020Recipient::GetOCERecipient(OCERecipient& oceRecipient) const
  619. {
  620.     BlockMove ( (Ptr) ((const OCERecipient*) fRecipient), (Ptr) & oceRecipient, sizeof ( oceRecipient ) );
  621.     return true;
  622. }
  623.  
  624. /***********************************|****************************************/
  625.  
  626. Boolean
  627. T2020Recipient::SetStatus ( RecipientStatusSet status )
  628. {
  629.     //    If we're setting the recipient to any status other than unknown, then
  630.     //    also mark the recipient as 'done' back to AOCE.  This will prevent AOCE
  631.     //    from telling us that we are responsible for this recipient should the
  632.     //    gateway crash after this operation but before the letter has been
  633.     //    completely sent.
  634.     if ((status != cUnknown) && (status != fStatus) && ( GetResponsible() == true ) ) {
  635.         fOwningLetter->MarkRecipient(this);
  636.     }
  637.     fStatus = status;
  638.  
  639.     return true;
  640. }
  641.  
  642. /***********************************|****************************************/
  643.  
  644. RecipientStatusSet
  645. T2020Recipient::GetStatus () const
  646. {
  647.     return fStatus;
  648. }
  649.  
  650. /***********************************|****************************************/
  651.  
  652. Boolean T2020Recipient::IsPathInfoPresent () const
  653. {
  654.     return true;    // OCERecipients always have path information
  655. }
  656.  
  657. /***********************************|****************************************/
  658.  
  659. Boolean T2020Recipient::IsPathInfoOptional () const
  660. {
  661.     #if 1
  662.     if ( ! fCheckedWhetherPathInformationIsOptional )
  663.     {
  664.         ((T2020Recipient*)this)->fIsPathInfoOptional = false;
  665.         
  666.         //    If the user is in the "Users & Groups" cluster, then the path information
  667.         //    might be optional -- only if there aren't any other recipients with the
  668.         //    same name in the "Users & Groups" cluster.
  669.         unsigned long recipientDNode;
  670.         if ( GetPathDNode ( recipientDNode )  )
  671.         {
  672.             TRString recipientName, recipientType;
  673.  
  674.             if ( GetRecipientName ( recipientName ) && GetRecipientType ( recipientType ) )
  675.             {    TRLI usersAndGroupsCluster ( fOwningLetter->GetHalfGateway()->GetAOCEDirectory(), 3 );
  676.                 TRecordID foundAddress;
  677.  
  678.                 unsigned long numberOfAddressesWithThisName = fOwningLetter->GetHalfGateway()->FindADASAddresses ( recipientName, recipientType, usersAndGroupsCluster, foundAddress, 2 );
  679.  
  680.                 if ( numberOfAddressesWithThisName == 1 )
  681.                     ((T2020Recipient*)this)->fIsPathInfoOptional = true;
  682.             }
  683.         }
  684.  
  685.         ((T2020Recipient*)this)->fCheckedWhetherPathInformationIsOptional = true;
  686.     }
  687.  
  688.     return fIsPathInfoOptional;
  689.  
  690.     #else
  691.  
  692.     return false; // eventually, change this.
  693.  
  694.     #endif
  695. }
  696.  
  697. /***********************************|****************************************/
  698.  
  699. Boolean T2020Recipient::IsNameAndPathUnique () const
  700. {
  701.     //    Check whether this recipient name is unique in it's cluster.  If it isn't, then
  702.     //     act like this recipient doesn't have a 'name', since the name/path information
  703.     //    won't be unique.
  704.     if ( ! fCheckedWhetherRecipientNameIsUnique )
  705.     {    unsigned long recipientDNode;
  706.  
  707.         if ( GetPathDNode ( recipientDNode ) )
  708.         {
  709.             TRLI userClusterRecord ( fOwningLetter->GetHalfGateway()->GetAOCEDirectory(), recipientDNode );
  710.             TRecordID foundAddress;
  711.             
  712.             unsigned long numberOfAddressesWithThisName =
  713.                 fOwningLetter->GetHalfGateway()->FindADASAddresses ( ((const DSSpec*) fRecipient)->entitySpecifier->local.recordName,
  714.                                                                      ((const DSSpec*) fRecipient)->entitySpecifier->local.recordType,
  715.                                                                      userClusterRecord, foundAddress, 2 );
  716.  
  717.             ((T2020Recipient *) this)->fCheckedWhetherRecipientNameIsUnique = true;
  718.             ((T2020Recipient *) this)->fRecipientNameIsUnique = ( numberOfAddressesWithThisName <= 1 );
  719.         }
  720.         else
  721.         {
  722.             //    Got an error; assume the name is unique ( almost always will be ) and go on.
  723.             ((T2020Recipient *) this)->fCheckedWhetherPathInformationIsOptional = false;
  724.             ((T2020Recipient *) this)->fRecipientNameIsUnique = true;
  725.         }
  726.     }
  727.  
  728.     return fRecipientNameIsUnique;
  729. }
  730.  
  731. /***********************************|****************************************/
  732.  
  733. Boolean T2020Recipient::IsAddressTypePresent () const
  734. {
  735.     return fRecipient.GetExtensionType() != kOCEentnDSSpec;
  736. }
  737.  
  738. /***********************************|****************************************/
  739.  
  740.